﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Autodesk.AutoCAD.Interop;
using Autodesk.AutoCAD.Interop.Common;
using System.IO;
using System.Collections;

namespace 根据高度图生成_TIN
{
    public partial class Form1 : Form
    {        
        Bitmap myMap;
        double maxZ, minZ, intervalZ, cadUnit;//最大的高程值，最小高程值，高程间差值，CAD中网格相邻两点的间距
 double basePointX, basePointY;//高度图左上角顶点在CAD中的坐标
        int mSize, nSize, gridUnit;//方阵网格的列数，方阵网格的行数，网格中相邻两点的间距
        double[,] pointsCoords;//方阵网格中各点所对应的高程值
        bool isOrNotSave = false;//是否保存了CAD文件        
        Autodesk.AutoCAD.Interop.AcadApplication AcadApp;        
        Autodesk.AutoCAD.Interop.AcadDocument AcadDoc;

        private void 保存CAD文件_Click(object sender, EventArgs e)
        {
            handle01:
            SaveFileDialog savefileDG = new SaveFileDialog();
            savefileDG.Filter = "AutoCAD 2007 DWG文件(*.dwg)|*.dwg"
            + "|AutoCAD 2007 DXF文件(*.dxf)|*.dxf"
            + "|AutoCAD 2004 DWG文件(*.dwg)|*.dwg"
            + "|AutoCAD 2004 DXF文件(*.dxf)|*.dxf"
            + "|AutoCAD 2000 DWG文件(*.dwg)|*.dwg"
            + "|AutoCAD 2000 DXF文件(*.dxf)|*.dxf";
            savefileDG.Title = "保存CAD文件";
            savefileDG.ShowDialog();

            string savePath = savefileDG.FileName;
            if (savePath == "")
            {
                MessageBox.Show("文件保存路径无效！");
                goto handle01;
            }
            switch (savefileDG.FilterIndex)
            {
                case 1:
                    AcadDoc.SaveAs(savePath, AcSaveAsType.ac2007_dwg, null);
                    break;
                case 2:
                    AcadDoc.SaveAs(savePath, AcSaveAsType.ac2007_dxf, null);
                    break;
                case 3:
                    AcadDoc.SaveAs(savePath, AcSaveAsType.ac2004_dwg, null);
                    break;
                case 4:
                    AcadDoc.SaveAs(savePath, AcSaveAsType.ac2004_dxf, null);
                    break;
                case 5:
                    AcadDoc.SaveAs(savePath, AcSaveAsType.ac2000_dwg, null);
                    break;
                case 6:
                    AcadDoc.SaveAs(savePath, AcSaveAsType.ac2000_dxf, null);
                    break;
            }
            isOrNotSave = true;
            MessageBox.Show("保存CAD文件成功!");
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (!isOrNotSave)
            {
                DialogResult returnResult;
                returnResult = MessageBox.Show("是否保存CAD文件？", "CAD文件未保存",
               MessageBoxButtons.YesNo);
                if (returnResult == DialogResult.Yes)
                {
                    保存CAD文件_Click(sender, e);
                }
            }
            AcadApp.Quit();

        }

        public Form1()
        {
            InitializeComponent();
        }

        private void 启动CAD()
        {
            try
            {
                AcadApp =
               (AcadApplication)System.Runtime.InteropServices.Marshal.GetActiveObject("AutoCAD.Application");
                AcadDoc = AcadApp.ActiveDocument;
            }
            catch
            {
                OpenFileDialog pOpenDG = new OpenFileDialog();
                pOpenDG.Filter = "CAD文件(*.dwg)|*.dwg|CAD图形文件(*.dxf)|*.dxf";
                pOpenDG.Title = "打开CAD文件";
                pOpenDG.ShowDialog();
                string filePath = pOpenDG.FileName;
                if (filePath == "")
                {
                    MessageBox.Show("选择CAD文件无效！", "文件无效！");
                    Application.Exit();
                }
                AcadApp = new AcadApplication();
                AcadDoc = AcadApp.Documents.Open(filePath, null, null);
            }
            AcadApp.Application.Visible = true;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            启动CAD();
        }

        private void 打开图片文件_Click(object sender, EventArgs e)
        {
            OpenFileDialog pOpenfileDG = new OpenFileDialog();
            pOpenfileDG.Title = "打开高度图";
            pOpenfileDG.Filter = "BMP文件(*.bmp)|*.bmp|Jpeg文件(*.jpg)|*.jpg|GIF文件(*.gif) | *.gif | TIFF文件(*.tif) | *.tif | 所有文件(*.*) | *.* "; 
 pOpenfileDG.ShowDialog();
            string filePath = "";
            filePath = pOpenfileDG.FileName;
            if (filePath == "")
            {
                MessageBox.Show("文件路径错误!");
                return;
            }
            myMap = new Bitmap(filePath);
            pictureBox1.Image = Image.FromFile(filePath);
        }

        private void 生成方阵网格点_Click(object sender, EventArgs e)
        {
            maxZ = Double.Parse(maxZTextBox.Text);
            minZ = Double.Parse(minZTextBox.Text);
            if (maxZ <= minZ)
            {
                MessageBox.Show("参数设置中最大高程小于最小高程值！", "错误!");
                return;
            }
            intervalZ = (maxZ - minZ) / 255;
            basePointX = Double.Parse(basePointXTextBox.Text);//高度图在CAD中的插入点X坐标
            basePointY = Double.Parse(basePointYTextBox.Text);//高度图在CAD中的插入点Y坐标
                                                              //生成方阵网格点
            gridUnit = Int16.Parse(gridDTextBox.Text);
            mSize = pictureBox1.Width / gridUnit;//行数
            nSize = pictureBox1.Height / gridUnit;//列数
            Color myColor = new Color();
            double tempZ;
            pointsCoords = new double[nSize, mSize];
            for (int i = 0; i < nSize; i++)
            {
                for (int j = 0; j < mSize; j++)
                {
                    myColor = myMap.GetPixel(j * gridUnit, i * gridUnit);
                    tempZ = (myColor.R + myColor.G + myColor.B) * intervalZ / 3 + minZ;
                    pointsCoords[i, j] = tempZ;
                }
            }
            //在CAD中绘制矩阵网格点
            AcadLayer gridPintLayer;
            gridPintLayer = AcadDoc.Layers.Add("方阵网格点");
            AcadDoc.ActiveLayer = gridPintLayer;
            cadUnit = Double.Parse(unitTextBox.Text);
            double[] cadPoint = new double[3];
            for (int i = 0; i < nSize; i++)
            {
                for (int j = 0; j < mSize; j++)
                {
                    cadPoint[0] = basePointX + cadUnit * j;
                    cadPoint[1] = basePointY - cadUnit * i;
                    cadPoint[2] = pointsCoords[i, j];
                    AcadDoc.ModelSpace.AddPoint(cadPoint);
                }
            }
            MessageBox.Show("生成方阵网格点完成！");
        }

        private void 生成TIN_Click(object sender, EventArgs e)
        {
            AcadLayer tinLayer;
            tinLayer = AcadDoc.Layers.Add("TIN");
            AcadDoc.ActiveLayer = tinLayer;
            double[] cadPoint01 = new double[3], cadPoint02 = new double[3], cadPoint03 = new
           double[3];
            for (int i = 0; i < nSize - 1; i++)
            {
                for (int j = 0; j < mSize - 1; j++)
                {
                    cadPoint01[0] = basePointX + cadUnit * j; cadPoint01[1] = basePointY - cadUnit *
                   i; cadPoint01[2] = pointsCoords[i, j];
                    cadPoint02[0] = basePointX + cadUnit * j; cadPoint02[1] = basePointY - cadUnit
                   * (i + 1); cadPoint02[2] = pointsCoords[i + 1, j];
                    cadPoint03[0] = basePointX + cadUnit * (j + 1); cadPoint03[1] = basePointY - cadUnit
                   * i; cadPoint03[2] = pointsCoords[i, j + 1];
                    AcadDoc.ModelSpace.Add3DFace(cadPoint01, cadPoint02, cadPoint03, cadPoint01);
                    cadPoint01[0] = basePointX + cadUnit * (j + 1); cadPoint01[1] = basePointY - cadUnit
                   * (i + 1); cadPoint01[2] = pointsCoords[i + 1, j + 1];
                    AcadDoc.ModelSpace.Add3DFace(cadPoint03, cadPoint02, cadPoint01, cadPoint03);
                }
            }
            MessageBox.Show("生成TIN完成！");
        }
    }
}
